﻿using Business.Core.Annotations;
using Business.Core.Result;
using Business.Data;
using Common;
using DataModel;
using LinqToDB;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using ProjectManagerSys;
using System.Text;
using ProjectManager.User.Model;
using ProjectManager.User;
using LinqToDB.Common.Internal.Cache;
using FangPage.Common;

namespace ProjectManagerSys
{
    /// <summary>
    /// 任务管理
    /// </summary>
    public class TaskMerber : Common.BusinessBase
    {
        MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions() { });

        [Doc("获取任务列表", Group = "任务管理")]
        public virtual async Task<dynamic> TaskList(int page, int limit, string taskname, string leadername,
            string membername, DateTime? startTime, DateTime? endTime,string projectname,string status)
        {
            try
            {
                using (var con = Data.DB.GetConnection())
                {

                    var list = con.MANAGER_TASK.AsQueryable();
                    //权限
                    AuthInfo authinfo = Logins.Authorize();
                    if (authinfo.isadmin != 1)
                    {
                        var new_user = "," + authinfo.userid + ",";
                        if (string.IsNullOrEmpty(authinfo.departs)) //个人
                        {
                            list = list.Where(c => c.CREATENAME == authinfo.userid || c.UPDATENAME == authinfo.userid || c.TASKLEADER.Contains(new_user) || c.TASKMEMBER.Contains(new_user) || c.APPROVALUSER.Contains(new_user));
                        }
                        else //部门
                        {
                            var arr_depart = authinfo.departid.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                            list = list.Where(c => arr_depart.Contains(c.DEPARTCODE) || arr_depart.Contains(c.UPDATECODE) || c.TASKLEADER.Contains(new_user) || c.TASKMEMBER.Contains(new_user) || c.APPROVALUSER.Contains(new_user));
                        }
                        //list = list.Where(c => c.CREATENAME == authinfo.userid || c.UPDATENAME == authinfo.userid || c.TASKLEADER.Contains(new_user) || c.TASKMEMBER.Contains(new_user));
                    }

                    list = list.Where(p => p.ACTIVE == 1);
                    if (string.IsNullOrWhiteSpace(projectname) == false) //项目名称
                        list = list.Where(p => p.PROJECTNAME.Contains(projectname));
                    if (string.IsNullOrWhiteSpace(taskname) == false) //任务名称
                        list = list.Where(p => p.TASKNAME.Contains(taskname));
                    if (string.IsNullOrWhiteSpace(leadername) == false)
                        list = list.Where(p => p.LEADERNAME.Contains(leadername));
                    if (string.IsNullOrWhiteSpace(membername) == false)
                        list = list.Where(p => p.MEMBERNAME.Contains(membername));
                    if (string.IsNullOrWhiteSpace(status) == false) // 任务状态
                        list = list.Where(p => p.TASKSTATUS == Convert.ToInt32(status));
                    list = startTime.HasValue && endTime.HasValue ? list = list.Where(p => p.TASKSTARTTIME >= startTime && p.TASKENDTIME <= endTime) : list;
                    list = list.OrderByDescending(p => p.TASKSTARTTIME);

                    var pageData = list.GetPaging(page, limit);

                    var result = new { code = 0, msg = "", count = pageData.Count, data = pageData.Data };

                    IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
                    timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
                    return JsonConvert.SerializeObject(result, Formatting.Indented, timeFormat);
                }
            }
            catch (Exception ex) { 

            }
            return null;
        }

        [Doc("新增任务", Group = "任务管理")]
        public virtual async Task<dynamic> AddTask(string arg)
        {
            var flag = 0;
            string message = "";
            try
            {
                MANAGER_TASK oTask = JsonConvert.DeserializeObject<MANAGER_TASK>(arg);

                //检查该时间段是否含有其他任务

                oTask.PROJECTNAME = (oTask.PROJECTNAME == "请选择关联项目") ? "" : oTask.PROJECTNAME;
                AuthInfo authinfo = Logins.Authorize();
                //FPLog.Info("loginuser", "【addtask】" + FPUtils.GetDateTime() + JsonConvert.SerializeObject(authinfo));
                oTask.CREATENAME = authinfo.userid;
                oTask.UPDATENAME = authinfo.userid;
                oTask.REALNAME = authinfo.realname;
                oTask.DEPARTCODE = authinfo.departid;
                oTask.UPDATECODE = authinfo.departid;
                oTask.REMINDTIMES = 0; //页面显示，真实时长
                oTask.CALREALNAME= 0; //用于计算，开始时间到结束时间的总时长

                oTask.UPDATETIME = DateTime.Now;
                oTask.ACTIVE = 1;

                if (!string.IsNullOrEmpty(oTask.TASKSTARTTIME.ToString()) && !string.IsNullOrEmpty(oTask.TASKENDTIME.ToString()))
                {
                    oTask.CALTOTAL = (decimal)CalculationWorkHour(oTask.TASKSTARTTIME, oTask.TASKENDTIME);
                    oTask.TOTALTIME = oTask.CALTOTAL - GetTaskByStartAndTimeFinish(oTask);
                }
                else
                {
                    oTask.CALTOTAL = 0;
                    oTask.TOTALTIME = 0;
                }

                using (var con = Data.DB.GetConnection())
                {
                    oTask.ID = Guid.NewGuid().ToString();
                    oTask.CREATETIME = DateTime.Now;
                    oTask.DELAYTIMES = 0;
                    oTask.REJECTTIMES = 0;
                    if (!string.IsNullOrEmpty(oTask.APPROVALUSER)) //选择有审批人的情况
                    {
                        oTask.APPROVALSTATUS = 0;
                    }
                    //入库之前检查该时间段是否含有其他任务
                    HandleInRangeTask(oTask);

                    //入库前检查任务是属于开发还是运维
                    if (!string.IsNullOrEmpty(oTask.PROJECTID))
                    {
                        var oPrpject = con.MANAGER_PROJECT.Where(c=>c.ID==oTask.PROJECTID).FirstOrDefault();
                        if (null != oPrpject)
                        {
                            oTask.TASKTYPE = (oPrpject.STATUS == 6 ? 2 : 1);
                        }
                    }

                    flag = await con.InsertAsync(oTask);
                    new LogDataOperation().TaskFlowLog(oTask.ID, "创建任务");
                    if (flag > 0 && !string.IsNullOrEmpty(oTask.ATTACHCODE))
                    {
                        string sql = string.Format("update BJSYS_ARRACH set UPDATETIME=sysdate,RESOURCEID='{0}',TABLENAME='MANAGER_TASK',EFFECT=1 where ATTACHCODE='{1}'", oTask.ID, oTask.ATTACHCODE);
                        con.ExecuteNonQuery(sql);
                    }
                    message = "添加成功";
                    //审批信息入库
                    if (!string.IsNullOrEmpty(oTask.APPROVALUSER))
                    {
                        string title = "任务标题为：" + oTask.TASKNAME + "的任务已提交，请审批";
                        new LogDataOperation().noticeLog(1,oTask.APPROVALUSER,oTask.ID, title, "MANAGER_TASK");
                    }
                    //任务流程入库
                    
                }

            }
            catch (Exception ex)
            {
                message = "添加失败，请联系技术人员";
                FPLog.Info("tasklog", "【addtask】" + FPUtils.GetDateTime() + ex.ToString());
                FPLog.Info("tasklog", "【addtask】" + FPUtils.GetDateTime() + ex.StackTrace);
                //throw ex;
            }
            var obj = new { flag = flag ,message= message };
            //入库的用户
            return JsonConvert.SerializeObject(obj);
        }

        [Doc("修改任务", Group = "任务管理")]
        public virtual async Task<dynamic> UpdateTask(string arg)
        {
            var flag = 0;
            try
            {
                MANAGER_TASK oTask = JsonConvert.DeserializeObject<MANAGER_TASK>(arg);

                using (var con = Data.DB.GetConnection())
                {
                    var oModel = con.MANAGER_TASK.Where(x => x.ID == oTask.ID).FirstOrDefault();
                    oModel.UPDATETIME = DateTime.Now;
                    oModel.ACTIVE = 1;
                    AuthInfo authinfo = Logins.Authorize();
                    oModel.UPDATECODE = authinfo.departid;
                    oModel.UPDATENAME = authinfo.userid;
                    oModel.PROJECTNAME = (oTask.PROJECTNAME == "请选择关联项目") ? "" : oTask.PROJECTNAME;
                    oModel.TASKNAME = oTask.TASKNAME;
                    oModel.TASKLEADER = oTask.TASKLEADER;
                    oModel.LEADERNAME = oTask.LEADERNAME;
                    oModel.MEMBERNAME = oTask.MEMBERNAME;
                    oModel.TASKMEMBER = oTask.TASKMEMBER;
                    oModel.APPROVALUSER = oTask.APPROVALUSER;
                    oModel.APPROVALNAME = oTask.APPROVALNAME;
                    oModel.TASKLEVEL = oTask.TASKLEVEL;
                    oModel.TASKTIP = oTask.TASKTIP;
                    oModel.PROJECTID = oTask.PROJECTID;
                    oModel.TASKDESC = oTask.TASKDESC;
                    oModel.ATTACHCODE = oTask.ATTACHCODE;
                    oModel.CALTOTAL = (decimal)CalculationWorkHour(oTask.TASKSTARTTIME, oTask.TASKENDTIME);

                    //1、如果时间发生改变，则重新计算时间，不管任务有没有自动往后延迟
                    if (!string.IsNullOrEmpty(oTask.TASKSTARTTIME.ToString()) && !string.IsNullOrEmpty(oTask.TASKENDTIME.ToString()))
                    {
                        if (oModel.TASKSTARTTIME != oTask.TASKSTARTTIME || oModel.TASKENDTIME != oTask.TASKENDTIME)
                        {
                            oModel.TOTALTIME = (decimal)CalculationWorkHour(oTask.TASKSTARTTIME, oTask.TASKENDTIME);
                        }
                       
                    }
                    else
                        oModel.TOTALTIME = 0;

                    oModel.CALTOTAL = (decimal)CalculationWorkHour(oTask.TASKSTARTTIME, oTask.TASKENDTIME);

                    //被驳回的任务
                    if (!string.IsNullOrEmpty(oTask.APPROVALUSER) && oModel.APPROVALSTATUS == 2)
                    {
                        string title = "任务标题为：" + oTask.TASKNAME + "的任务已重新提交，请审批";
                        new LogDataOperation().noticeLog(1, oTask.APPROVALUSER, oTask.ID, title, "MANAGER_TASK");
                        oModel.Y_APPROVALUSERIDS = "";
                    }

                    //入库之前检查该时间段是否含有其他任务
                    if (oModel.TASKENDTIME != oTask.TASKENDTIME || oModel.TASKSTARTTIME != oTask.TASKSTARTTIME)
                    {
                        oModel.TASKSTARTTIME = oTask.TASKSTARTTIME;
                        oModel.TASKENDTIME = oTask.TASKENDTIME;
                        //修改任务时，检测是否有已完成或者已验收的重叠任务
                        if (!string.IsNullOrEmpty(oTask.TASKSTARTTIME.ToString()) && !string.IsNullOrEmpty(oTask.TASKENDTIME.ToString()))
                            oModel.TOTALTIME = oModel.CALTOTAL - GetTaskByStartAndTimeFinish(oModel);
                        else oModel.TOTALTIME = 0;
                        HandleInRangeTask(oModel);
                    }
                    
                    //入库前检查任务是属于开发还是运维
                    if (!string.IsNullOrEmpty(oTask.PROJECTID))
                    {
                        var oPrpject = con.MANAGER_PROJECT.Where(c => c.ID == oTask.PROJECTID).FirstOrDefault();
                        if (null != oPrpject)
                        {
                            oModel.TASKTYPE = (oPrpject.STATUS == 6 ? 2 : 1);
                        }
                    }

                    
                    flag = await con.UpdateAsync(oModel);
                    new LogDataOperation().TaskFlowLog(oTask.ID, "修改任务");
                    if (flag > 0 && !string.IsNullOrEmpty(oTask.ATTACHCODE))
                    {
                        string sql = string.Format("update BJSYS_ARRACH set UPDATETIME=sysdate,RESOURCEID='{0}',TABLENAME='MANAGER_TASK',EFFECT=1 where ATTACHCODE='{1}'", oTask.ID, oTask.ATTACHCODE);
                        con.ExecuteNonQuery(sql);
                    }
                }

            }
            catch (Exception ex)
            {
                FPLog.Info("tasklog", "【UpdateTask】" + FPUtils.GetDateTime() + ex.ToString());
                FPLog.Info("tasklog", "【UpdateTask】" + FPUtils.GetDateTime() + ex.StackTrace);
                //throw ex;
            }

            //入库的用户
            return JsonConvert.SerializeObject(flag) ;
        }

        [Doc("获取任务详情", Group = "任务管理")]
        public virtual async Task<IResult> GetTaskInfo(string id)
        {
            using (var con = Data.DB.GetConnection())
            {
                var data = con.MANAGER_TASK.Where(x => x.ID == id).FirstOrDefault();
                if (null == data)
                {
                    return ResultCreate(-111);
                }
                return ResultCreate(data);
            }
        }

        [Doc("逻辑删除任务", Group = "任务管理")]
        public virtual async Task<dynamic> DeleteTask(string delIds)
        {
            using (var con = Data.DB.GetConnection())
            {
                var flag = 0;
                if (!String.IsNullOrEmpty(delIds))
                {
                    var idArray = delIds.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    if (idArray.Length > 0)
                    {
                        foreach (var item in idArray)
                        {
                            var oModel = con.MANAGER_TASK.Where(c => c.ID == item).FirstOrDefault();
                            if (oModel != null)
                            {
                                oModel.ACTIVE = 0;
                                flag += await con.UpdateAsync(oModel);
                            }
                        }
                    }
                }

                return (flag);
            }
        }

        [Doc("获取任务的字典", Group = "任务管理")]
        public virtual async Task<dynamic> GetDicList()
        {
            try
            {
                List<MANAGER_TASK_DIC> list = new List<MANAGER_TASK_DIC>();
                //缓存

                using (var con = Data.DB.GetConnection())
                {
                    list = con.MANAGER_TASK_DIC.Where(c => c.ACTIVE == 1).ToList();

                    return (list);
                }
            }
            catch (Exception ex) 
            {
                throw ex;
            }
            
        }

        [Doc("改变任务状态", Group = "任务管理")]
        public virtual async Task<dynamic> UpdateTaskStatus(string id,int status)
        {
            int flag = 0;
            string message = "";
            DateTime nowDate = DateTime.Now;
            AuthInfo authinfo = Logins.Authorize();
            try
            {
                using (var con = Data.DB.GetConnection())
                {
                    var data = con.MANAGER_TASK.Where(x => x.ID == id).FirstOrDefault();
                    if (null != data)
                    {
                        //记录任务操作日志
                        var diclist = con.MANAGER_TASK_DIC.Where(c => c.ACTIVE == 1).ToList();
                        //旧的内容
                        var oldmodel = diclist.Where(c => c.CODE == data.TASKSTATUS.ToString()).FirstOrDefault();
                        //新的内容
                        var newmodel = diclist.Where(c => c.CODE == status.ToString()).FirstOrDefault();
                        string detail = "任务状态从<span style='font-weigh:bold;'>" + (oldmodel == null ? "" : oldmodel.CODENAME) + "</span>修改为<span style='font-weigh:bold;'>" + (newmodel == null ? "" : newmodel.CODENAME) + "</span>";
                        string oldcontent = oldmodel == null ? "" : oldmodel.CODENAME;
                        string newcontent = newmodel == null ? "" : newmodel.CODENAME;

                        data.TASKSTATUS = status;
                        data.UPDATETIME = DateTime.Now;
                        if (status == 2) //已完成
                        {
                            if (data.TASKSTARTTIME > DateTime.Now) data.REALTIME = (decimal)0.1;
                            else
                            {
                                data.CALREALNAME = (decimal)CalculationWorkHour(data.TASKSTARTTIME, nowDate);
                                data.REALTIME = data.CALREALNAME - (data.CALTOTAL - data.TOTALTIME);
                            }
                            if (data.REALTIME > data.TOTALTIME && data.TASKENDTIME > DateTime.Now) //超时
                            {
                                data.OVERTIME = (data.REALTIME * 60 - data.TOTALTIME * 60) / 60;
                            }
                            else data.OVERTIME = 0;

                            //检查是否有其他暂停的任务,启用时间最靠近，优先级别最高的任务
                            string where = string.Format(" (CREATENAME='{0}' or UPDATENAME='{0}' or TASKLEADER like '%{1}%' or TASKMEMBER like '%{0}%') ", authinfo.userid, "," + authinfo + ",");
                            string SQL = string.Format("update manager_task set TASKSTATUS=1 where id=(select ID from (select * from manager_task where active=1 and TASKSTATUS=6  order by TASKSTARTTIME,TASKLEVEL desc) where rownum=1)");
                            con.ExecuteNonQuery(SQL);
                        }
                        if (status == 7) //已拒绝
                        {
                            data.REJECTTIMES += 1;
                            //驳回信息入库
                            new LogDataOperation().noticeLog(2, data.TASKLEADER.TrimEnd(',') + data.TASKMEMBER, data.ID, "标题为：" + data.TASKNAME + "任务已被驳回。", "MANAGER_TASK");
                        }

                        flag = await con.UpdateAsync(data);

                        new LogDataOperation().TaskFlowLog(data.ID, "任务状态", detail, oldcontent, newcontent);

                        message = (flag == 1 ? "修改成功" : "修改失败，请稍后重试");

                    }
                    else message = "未查找到数据，可能数据已被删除";
                    
                }
            }
            catch (Exception ex) {
                FPLog.Info("tasklog", "【UpdateTaskStatus】" + FPUtils.GetDateTime() + ex.ToString());
                FPLog.Info("tasklog", "【UpdateTaskStatus】" + FPUtils.GetDateTime() + ex.StackTrace);
            }
            return JsonConvert.SerializeObject(new { flag = flag, message = message });
        }

        [Doc("获取该用户最新任务的结束时间", Group = "任务管理")]
        public virtual async Task<dynamic> GetLastEndTime()
        {
            using (var con = Data.DB.GetConnection())
            {
                AuthInfo authinfo = Logins.Authorize();
                string new_userid = "," + authinfo.userid + ",";
                var oModel = con.MANAGER_TASK.Where(c => c.ACTIVE == 1 && c.TASKLEADER.Contains(new_userid) || c.TASKMEMBER.Contains(new_userid)).OrderByDescending(c=>c.TASKENDTIME).FirstOrDefault();
                DateTime? endTime = oModel == null ? null : oModel.TASKENDTIME;

                //获取用户的部门经理
                var names = "";
                var users = "";
                var myUser = con.BJSYS_USERINFO.Where(c=>c.ID == authinfo.userid).FirstOrDefault();
                if (myUser.CODE != 1)
                {
                    var oUser = con.BJSYS_USERINFO.Where(c => c.DEPARTID == authinfo.departid && c.CODE == 1).ToList();
                    if (oUser.Count > 0)
                    {
                        foreach (var item in oUser)
                        {
                            names += item.REALNAME + ",";
                            users += item.ID + ",";
                        }
                        names = names.TrimEnd(',');
                    }
                }
                

                IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
                timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
                var obj = new { endTime= endTime, names= names, users = users };
                return JsonConvert.SerializeObject(obj, Formatting.Indented, timeFormat);
            }
        }

        [Doc("任务审批", Group = "任务管理")]
        public virtual async Task<dynamic> TaskApproval(string taskid,string arg)
        {
            int flag = 0;
            try
            {
                using (var con = Data.DB.GetConnection())
                {
                    MANAGER_APPROVALLOG oAppraval = JsonConvert.DeserializeObject<MANAGER_APPROVALLOG>(arg);
                    AuthInfo authinfo = Logins.Authorize();
                    var oModel = con.MANAGER_TASK.Where(c => c.ACTIVE == 1 && c.ID == taskid).OrderByDescending(c => c.TASKENDTIME).FirstOrDefault();
                    //oModel.APPROVALNAME = authinfo.realname;
                    //oModel.APPROVALUSER = authinfo.userid;
                    oModel.APPROVALTIME = DateTime.Now;
                    oModel.APPROVALSTATUS = oAppraval.APPROVALSTATUS;
                    oModel.APPROVALREASON = oAppraval.APPROVALREASON;
                    oModel.Y_APPROVALUSERIDS =!string.IsNullOrEmpty(oModel.Y_APPROVALUSERIDS) ? oModel.Y_APPROVALUSERIDS + authinfo.userid + "," : "," + authinfo.userid + ",";
                    flag = await con.UpdateAsync(oModel);

                    //审批日志入库
                    oAppraval.ID = new Guid().ToString();
                    oAppraval.CREATENAME = authinfo.userid;
                    oAppraval.CREATETIME = DateTime.Now;
                    oAppraval.DEPARTCODE = authinfo.departid;
                    oAppraval.TASKID = taskid;
                    oAppraval.UPDATETIME = DateTime.Now;
                    oAppraval.ACTIVE = 1;
                    flag += await con.InsertAsync(oAppraval);
                    string detail = "审批结果为：" + (oModel.APPROVALSTATUS == 1 ? "同意" : "不同意") + "，原因：" + oAppraval.APPROVALREASON;
                    new LogDataOperation().TaskFlowLog(oModel.ID, "任务审批", detail, "", "");
                }
            }
            catch (Exception ex)
            { }
            return JsonConvert.SerializeObject(flag);
        }

        [Doc("获取任务日志", Group = "任务管理")]
        public virtual async Task<dynamic> GetTaskFlowLog(string taskid)
        {
            using (var con = Data.DB.GetConnection())
            {
                var list = con.MANAGER_TASKFLOWLOG.Where(c=>c.TASKID == taskid).OrderBy(c=>c.CREATETIME).ToList();
                IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
                timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
                return JsonConvert.SerializeObject(list, Formatting.Indented, timeFormat);
            }
        }

        [Doc("检查入库的任务时间里是否含有其他任务", Group = "任务管理")]
        public virtual async Task<dynamic> CheckTaskByTime(string arg)
        {
            List<MANAGER_TASK> list = new List<MANAGER_TASK>();
            MANAGER_TASK oTask = JsonConvert.DeserializeObject<MANAGER_TASK>(arg);
            if (!string.IsNullOrEmpty(oTask.TASKSTARTTIME.ToString()) && !string.IsNullOrEmpty(oTask.TASKENDTIME.ToString()))
            {
                list = GetTaskByStartAndTime(oTask);
            }
            IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
            timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
            var obj = new { count = list.Count,list = list};
            return JsonConvert.SerializeObject(obj,Formatting.Indented, timeFormat);
        }

        [Doc("提醒任务", Group = "任务管理")]
        public virtual async Task<dynamic> RemindTask(string delIds)
        {
            using (var con = Data.DB.GetConnection())
            {
                var flag = 0;
                if (!String.IsNullOrEmpty(delIds))
                {
                    var idArray = delIds.Split(new String[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    if (idArray.Length > 0)
                    {
                        foreach (var item in idArray)
                        {
                            var oModel = con.MANAGER_TASK.Where(c => c.ID == item).FirstOrDefault();
                            if (oModel != null)
                            {
                                oModel.REMINDTIMES = oModel.REMINDTIMES +1;
                                flag += await con.UpdateAsync(oModel);

                                //消息入库
                                
                                new LogDataOperation().noticeLog(5, oModel.TASKLEADER + oModel.TASKMEMBER,oModel.ID,"任务标题为：" + oModel.TASKNAME + "的任务已被" + oModel.REMINDTIMES + "次提醒，请尽快完成。", "MANAGER_TASK");
                            }
                        }
                    }
                }

                return (flag);
            }
        }

        /// <summary>
        ///计算开始时间到结束时间的有效工时
        /// </summary>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <returns></returns>
        public double CalculationWorkHour(DateTime? startTime,DateTime? endTime)
        {
            //计算思路：判断日期是不是同一天，是：直接计算出时间差， 不是：先计算除了开始当天和结束当天的时差
            double totalHour = 0;
            if (string.IsNullOrEmpty(startTime.ToString()) || string.IsNullOrEmpty(endTime.ToString()))
            {
                return totalHour;
            } 

            //1、判断两个时间
            DateTime newStart = Convert.ToDateTime(startTime);
            DateTime newEnd = Convert.ToDateTime(endTime);
            //取出上班安排时间
            string json = JsonFileHelp.ReadJsonFile(Environment.CurrentDirectory + "/appsettings.json", "worktime");
            worktimemodel oTime = JsonConvert.DeserializeObject<worktimemodel>(json);

            if (newStart.Date == newEnd.Date) //当天
            {
                totalHour = CalculationHour(newStart, newEnd, oTime);
            }
            else
            {
                //判断开始当天或者结束那天是不是节假日或者是否是周末，如果是节假日，就直接略过，如果是周末但不是补班，也直接略过
                //开始当天
                double start_curruent =(new TimeValidate().isHoliday(newStart)) ? 0 : CalculationHour(newStart, oTime.afternoon_end, oTime);
                //结束当天
                double end_curruent = (new TimeValidate().isHoliday(newEnd)) ? 0 : CalculationHour(oTime.morning_start, newEnd, oTime);
                totalHour = start_curruent + end_curruent;
                if (newStart.Date.AddDays(1) < newEnd.Date) //不是隔天
                {
                    //中间相隔的有几天
                    //计算任务的开始时间到结束时间的工作日
                    int w_days = DateOperation.GetWorkDays(newStart.Date.AddDays(1), newEnd.Date.AddDays(-1)); //周一到周五
                    int h_days = new TimeValidate().GetDays(newStart.Date.AddDays(1), newEnd.Date.AddDays(-1), 1);//节假日
                    int b_days = new TimeValidate().GetDays(newStart.Date.AddDays(1), newEnd.Date.AddDays(-1), 2);//补班
                    totalHour += (w_days - h_days + b_days) * oTime.total;
                }
            }
            return totalHour;
        }

        /// <summary>
        /// 以一天为期限，计算开始时间到结束时间的有效工时
        /// </summary>
        /// <param name="newStart">开始时间</param>
        /// <param name="newEnd">结束时间</param>
        /// <param name="oTime">上班设置</param>
        /// <returns></returns>
        public double CalculationHour(DateTime newStart, DateTime newEnd, worktimemodel oTime)
        {
            DateTime hour_minute_start = Convert.ToDateTime(newStart.Hour + ":" + newStart.Minute);
            DateTime hour_minute_end = Convert.ToDateTime(newEnd.Hour + ":" + newEnd.Minute);
            //1、计算开始时间到结束时间的总时差，精确到分钟

            //无效的选择时间
            if (hour_minute_start > hour_minute_end)
            {
                return 0;
            }
            //无效的上班时间,中午休息时间
            if (hour_minute_start >= oTime.morning_end && hour_minute_end <= oTime.afternoon_start)
            {
                return 0;
            }
            //无效的上班时间，结束时间早于早上上班时间或者开始时间晚于下午下班时间
            if (hour_minute_end < oTime.morning_start || hour_minute_start > oTime.afternoon_end)
            {
                return 0;
            }
            //不需要计算的情况,直接为一整天工作时间
            if (hour_minute_start <= oTime.morning_start && hour_minute_end >= oTime.afternoon_end)
            {
                return oTime.total;
            }
            double workHours = (hour_minute_end - hour_minute_start).TotalMinutes / 60;

            //上午的时间
            if (hour_minute_end < oTime.afternoon_start)
            {
                if (hour_minute_start < oTime.morning_start)
                {
                    //计算多余的时间
                    double yu = (oTime.morning_start - hour_minute_start).TotalMinutes / 60;
                    workHours = (workHours - yu);
                    workHours = workHours >= oTime.morningtotal ? oTime.morningtotal : workHours;
                }

                else workHours = workHours >= oTime.morningtotal ? oTime.morningtotal : workHours;
            }
            //下午的时间
            else if (hour_minute_start > oTime.morning_end)
            {
                if (hour_minute_end > oTime.afternoon_end)
                {
                    //计算多余的时间
                    double yu = ((hour_minute_end - oTime.afternoon_end).TotalMinutes) / 60;
                    workHours = (workHours - yu);
                    workHours = workHours >= oTime.afternoontotal ? oTime.afternoontotal : workHours;
                }
                else if (hour_minute_start < oTime.afternoon_start)
                {
                    double yu = ((oTime.afternoon_start - hour_minute_start).TotalMinutes) / 60;
                    workHours = (workHours - yu);
                    workHours = workHours >= oTime.afternoontotal ? oTime.afternoontotal : workHours;
                }
                else workHours = workHours >= oTime.afternoontotal ? oTime.afternoontotal : workHours;
            }
            //包含中午休息时间
            else
            {
                //除了中午没有无效的上班时间
                if (hour_minute_start >= oTime.morning_start && hour_minute_end <= oTime.afternoon_end)
                    workHours = ((workHours * 60) - (oTime.spacetotal * 60)) / 60;
                //有早上无效上班时间
                else if (hour_minute_start < oTime.morning_start)
                    workHours = ((workHours * 60) - ((oTime.morning_start - hour_minute_start).TotalMinutes) - (oTime.spacetotal * 60)) / 60;
                //有下午的无效上班时间
                else if (hour_minute_end > oTime.afternoon_end)
                    workHours = ((workHours * 60) - ((hour_minute_end - oTime.afternoon_end).TotalMinutes) - (oTime.spacetotal * 60)) / 60;
                else { }
            }

            return workHours;
        }

        /// <summary>
        /// 检查入库的任务的时间段是否含有其他任务，若含有，自动往后延
        /// </summary>
        /// <param name="oTask"></param>
        public async void HandleInRangeTask(MANAGER_TASK oTask)
        {
            if (string.IsNullOrEmpty(oTask.TASKSTARTTIME.ToString()) || string.IsNullOrEmpty(oTask.TASKENDTIME.ToString()))
                return;
            using(var con = Data.DB.GetConnection())
            {

                var list = GetTaskByStartAndTime(oTask);

                if (list.Count > 0) 
                {
                    //取出上班安排时间
                    string json = JsonFileHelp.ReadJsonFile(Environment.CurrentDirectory + "/appsettings.json", "worktime");
                    worktimemodel oTime = JsonConvert.DeserializeObject<worktimemodel>(json);
                    //在有任务的时间里穿插任务，总时长不变，结束时间自动延后
                    foreach (var item in list)
                    {
                        item.DELAYTIMES += (string.IsNullOrEmpty(item.DELAYTIMES.ToString()) ? 0 : item.DELAYTIMES);
                        item.OTHERTASKIDS = !string.IsNullOrEmpty(item.OTHERTASKIDS) ? item.OTHERTASKIDS + oTask.ID + "," : "," + oTask.ID + ",";
                        
                        if (item.TASKSTATUS == 1) item.TASKSTATUS = 6; //如果在进行中的，就暂停
                        DateTime minstartTime = oTask.TASKSTARTTIME > item.TASKSTARTTIME ? (DateTime)item.TASKSTARTTIME : (DateTime)oTask.TASKSTARTTIME;
                        DateTime maxEndTime = item.TASKENDTIME > oTask.TASKENDTIME ? (DateTime)item.TASKENDTIME : (DateTime)oTask.TASKENDTIME;
                        
                        //获取最大结束时间加上时差天数的的list
                        int days = (maxEndTime - minstartTime).Days + 1;
                        var timeList = DateOperation.GetWorkList(minstartTime, (days*2+2));
                        //获取最大结束时间到结束时间加上差值的补班
                        var testList = new TimeValidate().GetWeekOrWorkList(maxEndTime, maxEndTime.AddDays(days), 2);
                        var timelist2 = testList.Select(c => c.HOLIDAY).ToList();
                        //总
                        var totalTime = timeList.Union(timelist2).ToList<DateTime?>().OrderBy(c=>c.Value).ToArray();
                        ////获取最终结束时间的小时分钟
                        int index = 0;
                        string hourAndMinuter = new CalculateMatrixTime().LastTime(minstartTime, (int)(oTask.TOTALTIME * 60), (int)(item.CALTOTAL * 60), out index);
                        item.TASKENDTIME = Convert.ToDateTime(Convert.ToDateTime(totalTime[index-1]).ToString("yyyy-MM-dd")+" " + hourAndMinuter);
                        item.CALTOTAL = (decimal)CalculationWorkHour(item.TASKSTARTTIME, item.TASKENDTIME);

                        await con.UpdateAsync(item);    
                    }
                }
            }
            
        }

        /// <summary>
        /// 计算时间延后要加的完整时间
        /// </summary>
        /// <param name="TASKENDTIME"></param>
        /// <param name="oTime"></param>
        /// <param name="effectMinuter"></param>
        /// <returns></returns>
        public double GetCompleteMinuter(DateTime TASKENDTIME, worktimemodel oTime,double effectMinuter)
        {
            double complete = 0; //结束时间应该完整加的时间/单位分钟
            DateTime hour_minute_end = Convert.ToDateTime(Convert.ToDateTime(TASKENDTIME).ToString("HH:mm"));
            //计算出中午的休息时间，实体已包含

            //计算出下午下班到早上上班的休息时间
            TimeSpan nightTs = Convert.ToDateTime(oTime.morning_start).AddDays(1) - Convert.ToDateTime(oTime.afternoon_end);
            //计算出总休息时长/分钟
            double restMinuter = (24 - oTime.total) * 60;

            //结束时间在上班时间里的
            if ((hour_minute_end >= oTime.morning_start && hour_minute_end <= oTime.morning_end) ||
                (hour_minute_end >= oTime.morning_start && hour_minute_end <= oTime.morning_end))
            {
                //1、只加中午的休息时间的情况
                if (effectMinuter >= oTime.morningtotal * 60)
                {
                    complete = (oTime.spacetotal * 60) + (effectMinuter);
                }
                //2、只加下午的下班时间
                else if (effectMinuter > oTime.afternoontotal * 60)
                {
                    complete = (nightTs.TotalMinutes) + (effectMinuter);
                }
                //3、加一整天休息的情况
                else if (effectMinuter > oTime.afternoontotal * 60)
                {
                    complete = (restMinuter) + (effectMinuter);
                }
                //不用加任何空闲时间的，正常计算
                else
                {
                    complete = (effectMinuter);
                }
            }
            //结束时间不在上班时间里的
            else
            {
                //1、结束时间在早上上班时间前
                if (hour_minute_end < oTime.morning_start && effectMinuter <= oTime.morningtotal * 60)
                {
                    complete = (oTime.morning_start - hour_minute_end).TotalMinutes + (effectMinuter);
                }
                //2、结束时间在早上班时间后，并且在下午上班时前
                else if (hour_minute_end > oTime.morning_end && hour_minute_end < oTime.afternoon_start && effectMinuter <= oTime.afternoontotal * 60)
                {
                    complete = (oTime.afternoon_start - hour_minute_end).TotalMinutes + (effectMinuter);
                }
                //3、结束时间在下午下班时间后,并且有效时间只有早上的时间
                else if (hour_minute_end > oTime.afternoon_end)
                {
                    if (effectMinuter <= oTime.morningtotal * 30) //只有早上
                    {
                        complete = (Convert.ToDateTime("23:59:59") - hour_minute_end).TotalMinutes + (oTime.morning_start - Convert.ToDateTime("00:00:00")).TotalMinutes + (effectMinuter);
                    }
                    else//包含有下午
                    {
                        complete = (Convert.ToDateTime("23:59:59") - hour_minute_end).TotalMinutes + (oTime.morning_start - Convert.ToDateTime("00:00:00")).TotalMinutes + (effectMinuter) + oTime.spacetotal * 60;
                    }
                }
            }
            
            
            return complete;
        }

        /// <summary>
        /// 计算时间延后要加的完整时间
        /// </summary>
        /// <param name="TASKENDTIME"></param>
        /// <param name="oTime"></param>
        /// <param name="effectMinuter">有效</param>
        /// <returns></returns>
        public double GetCompleteMinuter2(DateTime TASKENDTIME, worktimemodel oTime, double effectMinuter)
        {
            double complete = 0; //结束时间应该完整加的时间/单位分钟
            DateTime hour_minute_end = Convert.ToDateTime(Convert.ToDateTime(TASKENDTIME).ToString("HH:mm"));
            //计算出中午的休息时间，实体已包含

            //计算出下午下班到早上上班的休息时间
            TimeSpan nightTs = Convert.ToDateTime(oTime.morning_start).AddDays(1) - Convert.ToDateTime(oTime.afternoon_end);
            //计算出总休息时长/分钟
            double restMinuter = (24 - oTime.total) * 60;

            //结束时间在上午的上班时间里
            if ((hour_minute_end >= oTime.morning_start && hour_minute_end <= oTime.morning_end)) 
            {
                TimeSpan ts = (oTime.morning_end - hour_minute_end);

            }
            //结束时间在下午的上班时间里
            else if((hour_minute_end >= oTime.morning_start && hour_minute_end <= oTime.morning_end))
            {

            }
            else
            {
                
            }


            return complete;
        }

        /// <summary>
        /// 返回负责人和协作者在开始时间和结束之间的其他任务
        /// </summary>
        /// <param name="oTask"></param>
        /// <returns></returns>
        public List<MANAGER_TASK> GetTaskByStartAndTime(MANAGER_TASK oTask)
        {
            List<MANAGER_TASK> list = new List<MANAGER_TASK>();
            using (var con = Data.DB.GetConnection())
            {
                if (string.IsNullOrEmpty(oTask.TASKLEADER) && string.IsNullOrEmpty(oTask.TASKMEMBER)) return list;

                string newstr = oTask.TASKLEADER.TrimEnd(',') + oTask.TASKMEMBER;
                string[] newarr = newstr.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).GroupBy(p => p).Select(p => p.Key).ToArray();
                string where = " 1=1 and (";
                for (var i = 0; i < newarr.Length; i++)
                {
                    if (i == newarr.Length - 1) where += string.Format(" CONCAT(TASKLEADER,TASKMEMBER) like '%,{0},%' ", newarr[i]);
                    else where += string.Format(" CONCAT(TASKLEADER,TASKMEMBER) like '%,{0},%' or ", newarr[i]);
                }

                where += " ) ";
                if (!string.IsNullOrEmpty(oTask.ID)) where += string.Format(" and id !='{0}' ",oTask.ID);

                //开始时间含在其他任务的时间段里并且不是已完成的任务和已验收的任务
                StringBuilder sql = new StringBuilder();
                sql.Append("select * from manager_task where id not in(select ID from manager_task ");
                sql.AppendFormat(" where to_date('{0}', 'yyyy-mm-dd hh24:mi:ss') >= TASKENDTIME", oTask.TASKSTARTTIME);
                sql.AppendFormat(" or to_date('{0}', 'yyyy-mm-dd hh24:mi:ss') <= TASKSTARTTIME)", oTask.TASKENDTIME);
                sql.AppendFormat(" and TASKSTATUS not in(2,3,4,7) and active = 1 and  TASKSTARTTIME is not null and TASKENDTIME is not null and {0} ", where);
                list = con.Execute<MANAGER_TASK>(sql.ToString()).ToList();
 
            }
            return list;
        }

        /// <summary>
        /// 计算已完成任务和已验收任务和当前任务重叠任务的有效时间
        /// </summary>
        /// <param name="oTask"></param>
        /// <returns></returns>
        public decimal GetTaskByStartAndTimeFinish(MANAGER_TASK oTask)
        {
            double totaltime = 0;
            using (var con = Data.DB.GetConnection())
            {
                if (string.IsNullOrEmpty(oTask.TASKLEADER) && string.IsNullOrEmpty(oTask.TASKMEMBER)) return 0;

                string newstr = oTask.TASKLEADER.TrimEnd(',') + oTask.TASKMEMBER;
                string[] newarr = newstr.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).GroupBy(p => p).Select(p => p.Key).ToArray();
                string where = " 1=1 and (";
                for (var i = 0; i < newarr.Length; i++)
                {
                    if (i == newarr.Length - 1) where += string.Format(" CONCAT(TASKLEADER,TASKMEMBER) like '%,{0},%' ", newarr[i]);
                    else where += string.Format(" CONCAT(TASKLEADER,TASKMEMBER) like '%,{0},%' or ", newarr[i]);
                }

                where += " ) ";
                if (!string.IsNullOrEmpty(oTask.ID)) where += string.Format(" and id !='{0}' ", oTask.ID);

                //开始时间含在其他任务的时间段里并且是已完成的任务和已验收的任务
                StringBuilder sql = new StringBuilder();
                sql.Append("select * from manager_task where id not in(select ID from manager_task ");
                sql.AppendFormat(" where to_date('{0}', 'yyyy-mm-dd hh24:mi:ss') >= TASKENDTIME", oTask.TASKSTARTTIME);
                sql.AppendFormat(" or to_date('{0}', 'yyyy-mm-dd hh24:mi:ss') <= TASKSTARTTIME)", oTask.TASKENDTIME);
                sql.AppendFormat(" and TASKSTATUS in(2,3) and active = 1 and  TASKSTARTTIME is not null and TASKENDTIME is not null and {0} ", where);
                var list = con.Execute<MANAGER_TASK>(sql.ToString()).ToList();
                if (list.Count > 0)
                {
                    List<OverlapModel> dic = new List<OverlapModel>();
                    foreach(var item in list)
                    {
                        if (item.TASKSTARTTIME <= oTask.TASKSTARTTIME && item.TASKENDTIME >= oTask.TASKENDTIME) 
                        {
                            //任务被包含的情况不算，因为任务被包含时，任务时间减去被包含时间，相当于没有时间啦
                        }
                        else
                        {
                            DateTime startTime = DateTime.Now;
                            DateTime endTime = DateTime.Now;
                            DateOperation.GetDateTime((DateTime)oTask.TASKSTARTTIME, (DateTime)oTask.TASKENDTIME, (DateTime)item.TASKSTARTTIME, (DateTime)item.TASKENDTIME, out startTime, out endTime);

                            dic.Add(new OverlapModel() { startTime =startTime, endTime = endTime });
                            dic = OverlapRecursion(dic,dic.Count,dic.Count);
                            
                        }                        
                    }
                    foreach (var item in dic)
                    {
                        totaltime += CalculationWorkHour(item.startTime, item.endTime);
                    }
                }
                
            }
            return (decimal)totaltime;
        }

        /// <summary>
        /// 递函数计算重叠部分
        /// </summary>
        /// <param name="dic"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public List<OverlapModel> OverlapRecursion(List<OverlapModel> dic,int n,int oldn)
        {
            List<OverlapModel> newDic = new List<OverlapModel>();
            if (oldn <= 1) return dic;
            //判断两个值是否有重叠
            if (dic.Count <= 1) return newDic;
            bool flag = DateOperation.isOverlap(dic[n-1].startTime,dic[n-1].endTime,dic[n-2].startTime,dic[n-2].endTime);
            if (flag)
            {
                DateTime MinStartTime = DateTime.Now;
                DateTime MaxEndTime = DateTime.Now;
                DateOperation.GetAllDateTime(dic[n - 1].startTime, dic[n - 1].endTime, dic[n - 2].startTime, dic[n - 2].endTime, out MinStartTime, out MaxEndTime);
                newDic.Add(new OverlapModel() { startTime = MinStartTime, endTime = MaxEndTime });
            }
            else
            {
                newDic.Add(new OverlapModel() { startTime = dic[n - 1].startTime, endTime = dic[n - 1].endTime });
                newDic.Add(new OverlapModel() { startTime = dic[n - 2].startTime, endTime = dic[n - 2].endTime });
            }
            //dic.Remove(dic[n - 1]);用最后一条数据一直跟前面的数据比较
            dic.Remove(dic[n - 2]);
            OverlapRecursion(dic,dic.Count, oldn);
            return newDic;
        }

        public class worktimemodel
        {
            /// <summary>
            /// //上午上班的开始时间
            /// </summary>
            public DateTime morning_start { set; get; }
            /// <summary>
            /// //上午上班的结束时间
            /// </summary>
            public DateTime morning_end { set; get; }
            /// <summary>
            /// //下午上班的开始时间
            /// </summary>
            public DateTime afternoon_start { set; get; }
            /// <summary>
            /// //下午上班的结束时间
            /// </summary>
            public DateTime afternoon_end { set; get; }
            /// <summary>
            /// //一天上班的总时间
            /// </summary>
            public double total { get; set; }
            /// <summary>
            /// //上午上班的总时间
            /// </summary>
            public double morningtotal { get; set; }
            /// <summary>
            /// //下午上班的总时间
            /// </summary>
            public double afternoontotal { get; set; }
            /// <summary>
            /// //中午休息时长
            /// </summary>
            public double spacetotal { get; set; } 
        }

        public class OverlapModel
        {
            public DateTime startTime { get; set; }
            public DateTime endTime { get; set; }
        }

    }
}
